package com.jiaqing.tooldesensitization.serialize;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.jiaqing.tooldesensitization.annotation.Desensitization;
import com.jiaqing.tooldesensitization.enums.DesensitizationTypeEnum;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Objects;

/**
 * @author: woniu
 * @Description 脱敏序列化
 * @ClassName DesensitizedSerialize
 * @Date 2023/4/17 21:57
 **/
@NoArgsConstructor
@AllArgsConstructor
// 定义一个类DesensitizationSerialize，继承JsonSerializer<String>并实现ContextualSerializer接口
public class DesensitizationSerialize extends JsonSerializer<String> implements ContextualSerializer {

    // 脱敏类型枚举
    private DesensitizationTypeEnum type;

    // 起始位置（包括）
    private Integer startInclude;

    // 结束位置（不包括）
    private Integer endExclude;

    // 重写serialize方法，用于将String类型的数据进行脱敏处理后写入JsonGenerator
    @Override
    public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 根据不同的脱敏类型进行不同的处理
        switch (type) {
            // 自定义范围脱敏
            case CUSTOMER:
                jsonGenerator.writeString(CharSequenceUtil.hide(str, startInclude, endExclude));
                break;
            // 用户ID脱敏
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId()));
                break;
            // 中文姓名脱敏
            case CHINESE_NAME:
                jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str)));
                break;
            // 身份证号码脱敏
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2));
                break;
            // 固定电话号码脱敏
            case FIXED_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str)));
                break;
            // 手机号码脱敏
            case MOBILE_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str)));
                break;
            // 地址脱敏
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str), 8));
                break;
            // 电子邮箱脱敏
            case EMAIL:
                jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str)));
                break;
            // 密码脱敏
            case PASSWORD:
                jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str)));
                break;
            // 中国车牌号脱敏
            case CAR_LICENSE:
                jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str)));
                break;
            // 银行卡号脱敏
            case BANK_CARD:
                jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str)));
                break;
            // 默认情况（不进行处理）
            default:
        }
    }

    // 重写createContextual方法，用于根据注解动态创建序列化实例
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            // 判断属性的数据类型是否为String类型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                // 获取属性上的Desensitization注解
                Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);
                // 如果没有在属性上找到注解，则在上下文中查找
                if (desensitization == null) {
                    desensitization = beanProperty.getContextAnnotation(Desensitization.class);
                }
                // 如果注解存在
                if (desensitization != null) {
                    // 创建并返回新的DesensitizationSerialize实例，传入注解中定义的type、startInclude和endExclude
                    return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(),
                            desensitization.endExclude());
                }
            }
            // 判断属性的数据类型不是String类型，则使用默认的序列化器
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        // 如果beanProperty为空，则返回处理null值的序列化器
        return serializerProvider.findNullValueSerializer(null);
    }
}
